<template>
  <div class="app-container">
    <el-row :gutter="10" class="card-list" justify="center">
      <el-col :span="6" v-for="(item, index) in animatedStats" :key="index">
        <el-card shadow="hover" class="art-custom-card">
          <div class="card-content">
            <span class="des subtitle">{{ item.des }}</span>
            <span class="number box-title">
                            {{ item.des.includes('率') ? item.displayNum.toFixed(1) + '%' : Math.floor(item.displayNum).toLocaleString() }}
                        </span>
            <div class="change-box">  
              <span class="change-text">较上周</span>
              <span :class="['change', item.change.includes('+') ? 'text-success' : 'text-danger']">
                                {{ item.change }}
                            </span>
            </div>
            <div class="icon-box">
              <component :is="item.icon" class="card-icon" />
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { User, UserFilled, Coin, PieChart } from '@element-plus/icons-vue'

const rawStats = [
  { des: '注册用户数', icon: User, num: 10432, change: '+15%' },
  { des: '活跃用户数', icon: UserFilled, num: 3280, change: '+8%' },
  { des: '付费用户数', icon: Coin, num: 980, change: '-5%' },
  { des: '用户留存率', icon: PieChart, num: 76, change: '+3%' },
    { des: '注册用户数', icon: User, num: 10432, change: '+15%' },
  { des: '活跃用户数', icon: UserFilled, num: 3280, change: '+8%' },
  { des: '付费用户数', icon: Coin, num: 980, change: '-5%' },
  { des: '用户留存率', icon: PieChart, num: 76, change: '+3%' }
]

const animatedStats = reactive(
  rawStats.map(item => ({ ...item, displayNum: 0 }))
)

const easeOutQuad = (t: number) => t * (2 - t)

const animateNumbers = () => {
  animatedStats.forEach(item => {
    const duration = 1000
    const start = performance.now()
    const target = item.num

    const step = (now: number) => {
      const elapsed = now - start
      const progress = Math.min(elapsed / duration, 1)
      const easedProgress = easeOutQuad(progress)
      item.displayNum = target * easedProgress
      if (progress < 1) {
        requestAnimationFrame(step)
      } else {
        item.displayNum = target
      }
    }

    requestAnimationFrame(step)
  })
}

onMounted(() => {
  animateNumbers()
})
</script>
<style scoped lang="scss">
.card-list {
  width: 100%;

  .el-col {
    margin-bottom: 10px;
  }

  .art-custom-card {
    position: relative;
    height: 140px;
    border-radius: 16px;
    transition: box-shadow 0.3s ease;

    &:hover {
      box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
    }

    .card-content {
      display: flex;
      flex-direction: column;
      justify-content: center;
      height: 100%;
      padding-left: 20px;
      padding-right: 60px;
      position: relative;

      .des {
        font-size: 14px;
      }

      .number {
        margin-top: 10px;
        font-size: 28px;
        font-weight: 500;
        color: #303133;
      }

      .change-box {
        display: flex;
        align-items: center;
        margin-top: 10px;

        .change-text {
          font-size: 13px;
          color: var(--el-text-color-secondary);
        }

        .change {
          margin-left: 5px;
          font-size: 13px;
          font-weight: bold;

          &.text-success::before {
            content: '↑ ';
            color: var(--el-color-success);
          }

          &.text-danger::before {
            content: '↓ ';
            color: var(--el-color-error);
          }
        }
      }

      .icon-box {
        position: absolute;
        top: 50%;
        right: 20px;
        transform: translateY(-50%);
        background: linear-gradient(135deg, #ecf5ff, #d9ecff);
        width: 48px;
        height: 48px;
        border-radius: 12px;
        display: flex;
        align-items: center;
        justify-content: center;
        box-shadow: 0 4px 8px rgba(64, 158, 255, 0.15);
        transition: all 0.3s ease;

        .card-icon {
          font-size: 18px;
          color: #409EFF;
          transition: transform 0.3s ease, color 0.3s ease;
        }

        &:hover .card-icon {
          transform: scale(1.15);
          color: #337ecc;
        }
      }
    }
  }
}

// 暗黑主题样式
.dark {
  .art-custom-card {
    background-color: #1e1e1e !important;
    color: #eee;

    .des,
    .number,
    .change-text {
      color: #ccc;
    }

    .icon-box {
      background: linear-gradient(135deg, #2c2c2c, #3a3a3a) !important;
    }

    .card-icon {
      color: #66b1ff !important;
    }

    .change.text-success::before {
      color: #67c23a;
    }

    .change.text-danger::before {
      color: #f56c6c;
    }
  }
}
</style>
